#pragma once

#include <iostream>
#include <fstream>
#include <cstdio>
#include <ctime>
#include <cstring>
#include <cstdarg>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include "LockGuard.hpp"
bool gIsSave = false;//是否保存到文件
const std::string logName = "log.txt";
#define LOG(level, format, ...)                                                \
    do                                                                         \
    {                                                                          \
        LogMessage(__FILE__, __LINE__, gIsSave, level, format, ##__VA_ARGS__); \
    } while (0)

#define EnableFile()    \
    do                  \
    {                   \
        gIsSave = true; \
    } while (0)
#define EnableScreen()   \
    do                   \
    {                    \
        gIsSave = false; \
    } while (0)




//确定日志等级
enum Level
{
    DEBUG = 0,
    INFO,
    WARNING,
    ERROR,
    FATAL
};


void SaveFile(const std::string& fileName,const std::string& message)
{
    std::ofstream out(fileName,std::ios::app);
    if(!out.is_open())
    {
        return;
    }
    out<<message;
    out.close();
}

std::string LevelToString(int level)
{
    switch(level)
    {
        case DEBUG:
            return "Debug";
        case INFO:
            return "Info";
        case WARNING:
            return "Warning";
        case ERROR:
            return "Error";
        case FATAL:
            return "Fatal";
        default:
            return "Unknown";
    }
}

std::string GetTimeString()
{
    time_t curr_time = time(nullptr);
    struct tm*format_time = localtime(&curr_time);
    if(format_time == nullptr)
    {
        return "None";
    }
    char time_buffer[1024];
    snprintf(time_buffer,sizeof(time_buffer),"%d-%d-%d %d:%d:%d",
                format_time->tm_year+1900,
                format_time->tm_mon+1,
                format_time->tm_mday,
                format_time->tm_hour,
                format_time->tm_min,
                format_time->tm_sec
            );
    return time_buffer;
}

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

//日志格式
//日志等级 时间 代码所在的文件名与行数，日志内容
void LogMessage(std::string fileName,int line,bool isSave,int level,const char* format,...)
{
    std::string levelStr = LevelToString(level);
    std::string timeStr = GetTimeString();
    pid_t selfid = getpid();
    char buffer[1024];
    va_list arg;
    va_start(arg,format);
    vsnprintf(buffer,sizeof(buffer),format,arg);
    va_end(arg);

    std::string message = "["+timeStr+"]"+"["+levelStr+"]"+
                          "["+std::to_string(selfid)+"]"+
                          "["+fileName+"]"+"["+std::to_string(line)+"]"+buffer;
    if(!isSave)
    {
        std::cout<<message<<std::endl;
    }
    else
    {
        SaveFile(logName,message);
    }

}

